package tomcat.socket;

import tomcat.common.CharType;
import tomcat.servlet.MyDefaultHttpServlet;
import tomcat.servlet.MyRequest;
import tomcat.servlet.MyResponse;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.Map;

/**
 * 自定义客户端连接处理器
 */
public class MySocketHandler {
    private static int num, begin, end;

    /**
     * 处理客户端连接
     */
    public static void handle(Socket socket, Map<String, HttpServlet> urlPatternMap) {
        num = 0;
        begin = 0;
        end = 0;

        MyRequest myRequest = getMyRequest(socket);
        MyResponse myResponse = new MyResponse(myRequest);

        try {
            String url = myRequest.getRequestURL().toString();
            System.out.println("url：" + url);
            //获取应用servlet
            HttpServlet httpServlet = urlPatternMap.get(url);
            if (httpServlet != null) {
                //servlet执行方法
                httpServlet.service(myRequest, myResponse);
                //发送响应参数
                myResponse.complete();
            } else {
                //构建默认servlet
                MyDefaultHttpServlet myDefaultHttpServlet = new MyDefaultHttpServlet();
                //servlet执行方法
                myDefaultHttpServlet.service(myRequest, myResponse);
                //发送响应参数
                myResponse.complete();
            }
        } catch (IOException | ServletException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 构建请求参数
     */
    private static MyRequest getMyRequest(Socket socket) {
        try {
            InputStream inputStream = socket.getInputStream();
            byte[] data = new byte[inputStream.available()];
            inputStream.read(data);

            //获取请求方法
            String method = getParam(data, CharType.SP, null);
            System.out.println("method：" + method);
            addNum(1);

            //获取请求url
            String url = getParam(data, CharType.SP, null);
            System.out.println("url：" + url);
            addNum(1);

            //获取协议
            String protocol = getParam(data, CharType.CR, CharType.LF);
            System.out.println("protocol：" + protocol);
            addNum(2);

            return new MyRequest(method, url, protocol, socket);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取参数
     */
    private static String getParam(byte[] data, Character c1, Character c2) {
        for (; num < data.length; num++, end++) {
            if (c2 == null) {
                if (data[num] == c1) {
                    break;
                }
            } else {
                if (data[num] == c1 && data[num + 1] == c2) {
                    break;
                }
            }
        }

        StringBuilder stringBuffer = new StringBuilder();
        for (; begin < end; begin++) {
            stringBuffer.append((char) data[begin]);
        }
        return stringBuffer.toString();
    }

    /**
     * 增加下标
     */
    private static void addNum(int i) {
        num += i;
        begin += i;
        end += i;
    }
}
